use anyhow::Error;

use crate::{
    cmd::{
        auth::Auth, collection::{create_collection::CreateCollection, delete_collection::DeleteCollection}, ping::Ping, save::Save, select::Select, unknown::Unknown, vector::{delete::Delete, insert::Insert, search::Search}
    },
    frame::Frame,
};

// 命令
pub enum Command {
    Insert(Insert),
    Delete(Delete),
    Search(Search),
    Select(Select),
    CreateCollection(CreateCollection),
    DeleteCollection(DeleteCollection),
    Auth(Auth),
    Ping(Ping),
    Unknown(Unknown),
    Save(Save),
}

impl Command {
    pub fn parse_from_frame(frame: Frame) -> Result<Self, Error> {
        let command_name = frame.get_arg(0).unwrap();
        let command = match command_name.to_uppercase().as_str() {
            "AUTH" => Command::Auth(Auth::parse_from_frame(frame)?),
            "PING" => Command::Ping(Ping::parse_from_frame(frame)?),
            "CREATE_COLLECTION" => Command::CreateCollection(CreateCollection::parse_from_frame(frame)?),
            "DELETE_COLLECTION" => Command::DeleteCollection(DeleteCollection::parse_from_frame(frame)?),
            "INSERT" => Command::Insert(Insert::parse_from_frame(frame)?),
            "SEARCH" => Command::Search(Search::parse_from_frame(frame)?),
            "SELECT" => Command::Select(Select::parse_from_frame(frame)?),
            "DELETE" => Command::Delete(Delete::parse_from_frame(frame)?),
            _ => Command::Unknown(Unknown::parse_from_frame(frame)?),
        };
        Ok(command)
    }
}